import jwt
from django.conf import settings
from django.contrib.auth import get_user_model, authenticate
from django.contrib.auth.models import Group
from django.contrib.auth.models import Permission
from djoser.serializers import (
    UserCreateSerializer as BaseUserCreateSerializer,
    UserSerializer as BaseUserSerializer,
)
from rest_framework import serializers
from rest_framework.exceptions import AuthenticationFailed
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer

from .models import Profile, GroupExtraInfo


class UserCreateSerializer(BaseUserCreateSerializer):
    class Meta(BaseUserCreateSerializer.Meta):
        fields = ["id", "username", "password"]


class UserSerializer(BaseUserSerializer):
    class Meta(BaseUserSerializer.Meta):
        fields = ["id", "username"]


class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
    def validate(self, attrs):
        username = attrs.get("username")
        password = attrs.get("password")

        # 查询用户名是否存在
        try:
            User = get_user_model()
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            # 提示用户名错误
            return {
                "data": None,
                "code": 0,
                "message": "用户不存在"
            }

        # 用户名存在，验证密码
        user = authenticate(username=username, password=password)

        if user is None:
            # 提示密码错误
            return {
                "data": None,
                "code": 0,
                "message": "密码错误"
            }

        # 成功验证用户后，生成 JWT
        data = super().validate(attrs)
        access_token = data["access"]
        try:
            payload = jwt.decode(
                access_token, settings.SIMPLE_JWT["SIGNING_KEY"], algorithms=["HS256"]
            )
        except jwt.ExpiredSignatureError:
            raise AuthenticationFailed("token is expired")
        except jwt.DecodeError:
            raise AuthenticationFailed("Error decoding token")

        user = self.user
        payload['type'] = 'local'
        payload["user_id"] = user.id
        payload["username"] = user.username
        permissions = list(user.get_all_permissions())
        permissions = [f"{perm.split('.')[1]}" for perm in permissions]
        # 为了跟前端适配，虽然名为 roles，但表示的是权限列表
        payload["roles"] = permissions
        payload["job_number"] = ""

        new_access_token = jwt.encode(
            payload, settings.SIMPLE_JWT["SIGNING_KEY"], algorithm="HS256"
        )

        return {
            "data": {
                "access": new_access_token,
                "refresh": data["refresh"],
            },
            "code": 0,
            "message": "Authentication successful",
        }


class ProfileSerializer(serializers.ModelSerializer):
    user = UserSerializer(read_only=True)
    groups = serializers.SerializerMethodField()
    # 为了跟前端适配，虽然名为 roles，但表示的是权限列表
    roles = serializers.SerializerMethodField()
    """权限列表"""

    class Meta:
        model = Profile
        fields = ["id", "user", "chinese_name", "groups", "roles"]

    def get_groups(self, obj):
        user = obj.user
        group_names = [group.name for group in user.groups.all()]
        return group_names

    def get_roles(self, obj):
        """获取权限列表"""
        user = obj.user
        permissions = list(user.get_all_permissions())
        permissions = [f"{perm.split('.')[1]}" for perm in permissions]
        return permissions


class PermissionSerializer(serializers.ModelSerializer):
    class Meta:
        model = Permission
        fields = ["id", "codename", "name"]


class GroupSerializer(serializers.ModelSerializer):
    code_name = serializers.CharField(source='extra_info.code_name', required=False)
    permissions = PermissionSerializer(many=True, read_only=True)
    user_set = UserSerializer(many=True, read_only=True)

    class Meta:
        model = Group
        fields = ["id", "name", "permissions", 'user_set', 'code_name']
        read_only_fields = ["id"]  # id 是只读字段，不需要在创建时传递

    def create(self, validated_data):
        # 从 validated_data 中提取 extra_info 的数据
        extra_info_data = validated_data.pop('extra_info', {})
        group = super().create(validated_data)

        # 创建 GroupExtraInfo 实例
        if 'code_name' in extra_info_data:
            GroupExtraInfo.objects.create(group=group, code_name=extra_info_data['code_name'])

        return group

    def update(self, instance, validated_data):
        # 从 validated_data 中提取 extra_info 的数据
        extra_info_data = validated_data.pop('extra_info', {})
        instance = super().update(instance, validated_data)

        # 更新 GroupExtraInfo 实例
        if 'code_name' in extra_info_data:
            extra_info, created = GroupExtraInfo.objects.get_or_create(group=instance)
            extra_info.code_name = extra_info_data['code_name']
            extra_info.save()

        return instance
